package com.ym.medical.service.impl;

import com.ym.core.exception.BusinessException;
import com.ym.core.utils.DateKit;
import com.ym.core.utils.tkmybatis.BaseSVImpl;
import com.ym.core.utils.tkmybatis.TK;
import com.ym.medical.dao.UserHealthRecordDao;
import com.ym.medical.domain.bo.PublishCouponTarget;
import com.ym.medical.domain.entity.AccountEntity;
import com.ym.medical.domain.entity.CouponEntity;
import com.ym.medical.domain.entity.HealthCoinSourceSettingEntity;
import com.ym.medical.domain.entity.UserHealthRecordEntity;
import com.ym.medical.domain.param.HealthCoinSourceSettingParam;
import com.ym.medical.domain.param.UserHealthRecordParam;
import com.ym.medical.domain.vo.UserAndHealthCoinSettingVO;
import com.ym.medical.domain.vo.UserHealthRecordVo;
import com.ym.medical.enums.ComputeWayEnum;
import com.ym.medical.enums.CouponSendWayEnum;
import com.ym.medical.enums.HealthCoinSourceEnum;
import com.ym.medical.enums.SysValidEnum;
import com.ym.medical.service.IAccountSV;
import com.ym.medical.service.ICouponReceiveRecordSV;
import com.ym.medical.service.IHealthCoinSourceSettingSV;
import com.ym.medical.service.IUserHealthRecordSV;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * ComputerName:LAPTOP-I6GKDIFQ
 * Author:admin
 * Date: 2019-08-27
 * Time: 17:05:27
 * 健康币变动表服务实现类
 */
@Service
@Transactional(rollbackFor = {Exception.class})
public class UserHealthRecordSVImpl extends BaseSVImpl<UserHealthRecordEntity, UserHealthRecordDao> implements IUserHealthRecordSV {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserHealthRecordSVImpl.class);
    @Autowired
    private IAccountSV accountSV;

    @Autowired
    private IHealthCoinSourceSettingSV healthCoinSourceSettingSV;
    @Autowired
    private ICouponReceiveRecordSV couponReceiveRecordSV;

    @Override
    public void addHealthCoin(UserHealthRecordParam userHealthRecord){
        //1.查询某个渠道获取健康币的数量
        if(userHealthRecord.getSource() != null && !HealthCoinSourceEnum.CASH_COUPON.getKey().equals(userHealthRecord.getSource())){
            userHealthRecord.setNum(getHealthCoinNum(userHealthRecord.getSource()));
            //2. 增加健康币变动记录
            userHealthRecord.setCreateSb(userHealthRecord.getUserId());
            this.insert(userHealthRecord.covert());
            //3. 账户余额变动
            BigDecimal num = new BigDecimal(userHealthRecord.getNum());
            AccountEntity account = accountSV.selectAccountByUserId(userHealthRecord.getUserId());
            if(ComputeWayEnum.INCREASE.getKey().equals(userHealthRecord.getIncDec())){
                account.setCoinBalance(account.getCoinBalance().add(num));
            }else if(ComputeWayEnum.TO_REDUCE.getKey().equals(userHealthRecord.getIncDec())){
                account.setCoinBalance(account.getCoinBalance().subtract(num));
            }
            accountSV.updateById(account);
        }
    }

    @Override
    public UserHealthRecordVo checkHealthCoin(Long userId, String source, String incDec){
        UserHealthRecordParam userHealthRecordParam = new UserHealthRecordParam();
        userHealthRecordParam.setUserId(userId);
        userHealthRecordParam.setSource(source);
        userHealthRecordParam.setIncDec(incDec);
        //查询该患者有没有获取过健康币
        List<UserHealthRecordEntity> userHealthRecords = this.selectList(
                TK.select(UserHealthRecordEntity.class).where()
                .andEqualTo(UserHealthRecordEntity::getUserId,userId)
                .andEqualTo(UserHealthRecordEntity::getSource,source)
                .andEqualTo(UserHealthRecordEntity::getIncDec,incDec)
                .end()
                .orderByClause("id desc")
        );

        int continueDays = 0;
        String now = DateKit.getBeforeTime(DateKit.parseDate(DateKit.getDate()),0,0,-1,0,0,0,DateKit.YYYY_MM_DD);
        for (UserHealthRecordEntity record : userHealthRecords) {
            if(HealthCoinSourceEnum.SIGN_IN.getKey().equals(record.getSource())){
                String recordDate = DateKit.dateTime(record.getCreateTime());
                if(DateKit.getDate().equals(recordDate)){
                    LOGGER.info("该用户当天已经通过签到渠道获取过健康币了");
                    return null;
                }
                if(recordDate.equals(now)){
                    continueDays +=1;
                    now = DateKit.getBeforeTime(DateKit.parseDate(now),0,0,-1,0,0,0,DateKit.YYYY_MM_DD);
                }
            }else if (HealthCoinSourceEnum.BINDING_MOBILE_PHONE_NUMBER.getKey().equals(record.getSource())){
                LOGGER.info("该用户已经通过授权手机号渠道获取过健康币了");
                return null;
            }else if (HealthCoinSourceEnum.SET_HEAD.getKey().equals(record.getSource())){
                LOGGER.info("该用户已经通过设置头像渠道获取过健康币了");
                return null;
            }
        }
        //连续签到天数
        userHealthRecordParam.setContinueDays(continueDays+1);
        //增加健康币变动
        addHealthCoin(userHealthRecordParam);
        //获取邀请好友获得的金币数量
        userHealthRecordParam.setInviteGetNum(getHealthCoinNum(HealthCoinSourceEnum.INVITE_FRIENDS.getKey()));
        UserHealthRecordVo userHealthRecordVo = new UserHealthRecordVo();
        BeanUtils.copyProperties(userHealthRecordParam,userHealthRecordVo);
        return userHealthRecordVo;
    }

    /**
     * 某用户连续签到天数
     * @param userId
     * @return
     */
    public int getContinueDays(Long userId) {
        List<UserHealthRecordEntity> userHealthRecordList = this.selectList(
                TK.select(UserHealthRecordEntity.class).where()
                .andEqualTo(UserHealthRecordEntity::getUserId, userId)
                .andEqualTo(UserHealthRecordEntity::getSource,HealthCoinSourceEnum.SIGN_IN.getKey())
                .end()
                .orderByClause("create_time desc")
        );
        int continueDays = 0;
        String now =DateKit.getBeforeTime(DateKit.parseDate(DateKit.getDate()),0,0,-1,0,0,0,DateKit.YYYY_MM_DD);
        for (UserHealthRecordEntity record : userHealthRecordList) {
            String recordDate = DateKit.parseDateToStr(DateKit.YYYY_MM_DD, record.getCreateTime());
            if(recordDate.equals(now)){
                continueDays +=1;
                now = DateKit.getBeforeTime(DateKit.parseDate(now),0,0,-1,0,0,0,DateKit.YYYY_MM_DD);
            }else {
                //段签了
                return 0;
            }
        }
        return continueDays;
    }

    @Override
    public void exchangeCoupon(CouponEntity coupon, Long userId) {
        //1. 增加健康币变动记录
        UserHealthRecordEntity record = new UserHealthRecordEntity();
        record.setUserId(userId);
        record.setSource(HealthCoinSourceEnum.CASH_COUPON.getKey());
        record.setIncDec(ComputeWayEnum.TO_REDUCE.getKey());
        record.setNum(coupon.getBuyGold().intValue());
        record.setCreateSb(userId);
        this.insert(record);
        //2. 账户余额变动
        BigDecimal num = new BigDecimal(record.getNum());
        AccountEntity account = accountSV.selectAccountByUserId(record.getUserId());
        if(account.getCoinBalance().doubleValue() < record.getNum().doubleValue() ) {
            throw new BusinessException("健康币余额不足");
        }
        account.setCoinBalance(account.getCoinBalance().subtract(num));
        accountSV.updateById(account);

        //3. 增加优惠劵领取记录 (最后一个代表业务字段 健康币变动记录id)
        PublishCouponTarget couponTarget = new PublishCouponTarget();
        couponTarget.setUserId(userId);
        couponTarget.setPatientId(null);
        couponReceiveRecordSV.publishCoupon(coupon.getId(), CouponSendWayEnum.EXCHANGE.getKey(),record.getId(),userId,null,couponTarget);
    }

    /**
     * 查询某个渠道获取健康币的数量
     * @param source
     * @return
     */
    @Override
    public Integer getHealthCoinNum(String source) {
        List<HealthCoinSourceSettingEntity> healthCoinSourceSettings = healthCoinSourceSettingSV.selectList(
                TK.select(HealthCoinSourceSettingEntity.class).where()
                .andEqualTo(HealthCoinSourceSettingEntity::getValid,SysValidEnum.VALID.getKey())
                .andEqualTo(HealthCoinSourceSettingEntity::getSourceType,source)
                .end()
                .orderByClause("id desc")
        );
        if(!healthCoinSourceSettings.isEmpty()){
            //时间限制(开始时间--结束时间之内)
           /* for (HealthCoinSourceSetting healthCoinSourceSetting : healthCoinSourceSettings) {
                if(new Date().before(healthCoinSourceSetting.getStartTime()) || new Date().after(healthCoinSourceSetting.getEndTime())){
                        LOGGER.info("当前健康币还未发行,详情咨询管理员!");
                        return 0;
                }
            }*/
            HealthCoinSourceSettingEntity healthCoinSourceSetting = healthCoinSourceSettings.get(0);
            /*if(healthCoinSourceSetting.getLimitNum() > 0){
                //有上限
                //查询该健康币发布时间段内所有的健康币变动记录
                String startTime = DateKit.parseDateToStr(DateKit.YYYY_MM_DD_HH_MM_SS, healthCoinSourceSetting.getStartTime());
                String endTime = DateKit.parseDateToStr(DateKit.YYYY_MM_DD_HH_MM_SS, healthCoinSourceSetting.getEndTime());
                UserHealthRecordModel userHealthRecordModel = new UserHealthRecordModel();
                userHealthRecordModel.setSource(source);
                userHealthRecordModel.setIncDec(ComputeWayEnum.INCREASE.getKey());
                userHealthRecordModel.setQueryByWhereClause("where create_time >= '"+startTime+"' AND create_time <'"+endTime+"'");
                List<UserHealthRecord> userHealthRecords = selectByModel(userHealthRecordModel);
                if(healthCoinSourceSetting.getLimitNum() <= userHealthRecords.size()){
                    LOGGER.info("当日健康币已经领取完了");
                    return 0;
                }
            }*/
            return healthCoinSourceSetting.getEveyNum();
        }
        LOGGER.info("当前健康币还未发行,详情咨询管理员!");
        return 0;
    }

    @Override
    public UserAndHealthCoinSettingVO selectUserSignAndAuth(Long userId) {
        UserAndHealthCoinSettingVO userAndHealthCoinSettingVO = new UserAndHealthCoinSettingVO();
        userAndHealthCoinSettingVO.setUserId(userId);
        userAndHealthCoinSettingVO.setSignIn(false);
        userAndHealthCoinSettingVO.setAuthPhone(false);
        List<UserHealthRecordEntity> userHealthRecords = this.selectList(
                TK.select(UserHealthRecordEntity.class).where()
                .andIn(UserHealthRecordEntity::getSource,new String[]{"01","04"})
                .andEqualTo(UserHealthRecordEntity::getUserId,userId)
                .end()
        );
        for (UserHealthRecordEntity userHealthRecord : userHealthRecords) {
            //查询用户是否授权手机号
            if(HealthCoinSourceEnum.BINDING_MOBILE_PHONE_NUMBER.getKey().equals(userHealthRecord.getSource())){
                userAndHealthCoinSettingVO.setAuthPhone(true);
            }
            if(HealthCoinSourceEnum.SIGN_IN.getKey().equals(userHealthRecord.getSource())){
                //当天是否签到
                if(DateKit.getDate().equals(DateKit.dateTime(userHealthRecord.getCreateTime()))){
                    userAndHealthCoinSettingVO.setSignIn(true);
                }
            }
        }
        return userAndHealthCoinSettingVO;
    }

    @Override
    public UserAndHealthCoinSettingVO checkUserCondition(Long userId) {
        UserAndHealthCoinSettingVO userAndHealthCoinSettingVO = new UserAndHealthCoinSettingVO();
        List<HealthCoinSourceSettingEntity> healthCoinSourceSettings = healthCoinSourceSettingSV.checkUserCondition();
        for (HealthCoinSourceSettingEntity healthCoinSourceSetting : healthCoinSourceSettings) {
            int num = healthCoinSourceSetting.getEveyNum();
            if(HealthCoinSourceEnum.SIGN_IN.getKey().equals(healthCoinSourceSetting.getSourceType())){
                userAndHealthCoinSettingVO.setSignInNum(num);
            } else if(HealthCoinSourceEnum.TOP_UP.getKey().equals(healthCoinSourceSetting.getSourceType())){
                userAndHealthCoinSettingVO.setRechargeNum(num);
            }else if(HealthCoinSourceEnum.INVITE_FRIENDS.getKey().equals(healthCoinSourceSetting.getSourceType())){
                userAndHealthCoinSettingVO.setInviteNum(num);
            }else if(HealthCoinSourceEnum.BINDING_MOBILE_PHONE_NUMBER.getKey().equals(healthCoinSourceSetting.getSourceType())){
                userAndHealthCoinSettingVO.setAuthPhoneNum(num);
            }else if(HealthCoinSourceEnum.SET_HEAD.getKey().equals(healthCoinSourceSetting.getSourceType())){
                userAndHealthCoinSettingVO.setSetHeadNum(num);
            }
        }
        //查询该用户当天是否签到 是否授权
        UserAndHealthCoinSettingVO userSignAndAuth = selectUserSignAndAuth(userId);
        userAndHealthCoinSettingVO.setSignIn(userSignAndAuth.getSignIn());
        userAndHealthCoinSettingVO.setAuthPhone(userSignAndAuth.getAuthPhone());
        return userAndHealthCoinSettingVO;
    }
}
